package com.kkelectronics.w2b.devplugin.codegenerator.core.databean;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;

import com.kkelectronics.w2b.beangen.service.model.BeanClass;
import com.kkelectronics.w2b.devplugin.codegenerator.model.Field;
import com.kkelectronics.w2b.devplugin.codegenerator.util.ASTProvider;

@SuppressWarnings("unchecked")
public class InterfaceGenerator {

	public CompilationUnit gen(final BeanClass bean, final List<Field> fields) {
		try {
			final AST ast = ASTProvider.get();

			final CompilationUnit cu = ast.newCompilationUnit();

			final PackageDeclaration p1 = ast.newPackageDeclaration();
			p1.setName(ast.newName(bean.getPackageName()));
			cu.setPackage(p1);

			final TypeDeclaration td = ast.newTypeDeclaration();
			td.setInterface(true);
			td.setName(ast.newSimpleName(bean.getClassName()));

			cu.types().add(td);

			final List<Name> importTypes = new LinkedList<Name>();

			for (final Field field : fields) {

				fillListWithUniqueNames(importTypes, field.getImportTypes());

				td.bodyDeclarations().add(CodeGenerator.genSetMethodSignature(ast, field));

				td.bodyDeclarations().add(CodeGenerator.genGetMethodSignature(ast, field));
			}
			ImportDeclaration newImport;
			for (final Name name : importTypes) {
				newImport = ast.newImportDeclaration();
				newImport.setName(name);
				cu.imports().add(newImport);
			}
			return cu;
		} catch (final Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}

	private void fillListWithUniqueNames(final List<Name> fillList, final Collection<Name> inList) {
		if (fillList.isEmpty()) {
			fillList.addAll(inList);
		} else {
			boolean condition;
			for (final Name in : inList) {
				condition = true;
				for (final Name name : fillList) {
					if (name.toString().equals(in.toString())) {
						condition = false;
						break;
					}
				}
				if (condition) {
					fillList.add(in);
				}
			}
		}
	}
}
